using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;

namespace GameEditor.Common.Designer
{
    public enum DesignerAnchor
    {
        East=1,
        West=2,
        NorthEast=3,
        NorthWest=4,
        North=5,
        South=6,
        SouthEast=7,
        SouthWest=8
    }
    public class DesignerController : RenderableObject
    {
        public enum DesignerState
        {
            Resizing,
            Moving
        }
        public static readonly int AnchorHalfSize = 3;
        private DesignerState state; 
        private int anchorVisibility;
        private Control delegationObject;

        public DesignerState State
        {
            get { return state; }
            set
            {
                state = value;
            }
        }
        private bool isReference = false;

        public bool IsReference
        {
            get { return isReference; }
            set { isReference = value; }
        }






        public Control DelegationObject
        {
            get { return delegationObject; }
        }

        public void SetAnchorVisible(DesignerAnchor anchor, bool visible)
        {
            int a = 1 << (int)anchor;
            anchorVisibility = (anchorVisibility ^ a) | a;
        }
        public bool GetAnchorVisible(DesignerAnchor anchor)
        {
            int a = 1 << (int)anchor;
            return 0 != (anchorVisibility & a);
        }
        private bool AnchorIntersects(Point pt, int cx, int cy)
        {
            int x = pt.X;
            int y = pt.Y;
            return (x > (cx - AnchorHalfSize))
            && (x < (cx + AnchorHalfSize))
            && (y > (cy - AnchorHalfSize))
            && (y < (cy + AnchorHalfSize));


        }
        public Nullable<DesignerAnchor> PickAnchor(Point pt)
        {
            //draw anchors
            Rectangle rect = delegationObject.TransformedGeometry;
            int left = rect.Left;
            int top = rect.Top;
            int bottom = rect.Bottom;
            int right = rect.Right;
            if (AnchorIntersects(pt, left - AnchorHalfSize, top - AnchorHalfSize))
                return DesignerAnchor.NorthWest;
            if (AnchorIntersects(pt, (left + right) >> 1, top - AnchorHalfSize))
                return DesignerAnchor.North;

            if (AnchorIntersects(pt, right + AnchorHalfSize, top - AnchorHalfSize))
                return DesignerAnchor.NorthEast;

            if (AnchorIntersects(pt, right + AnchorHalfSize, (top + bottom) >> 1))
                return DesignerAnchor.East;

            if (AnchorIntersects(pt, right + AnchorHalfSize, bottom + AnchorHalfSize))
                return DesignerAnchor.SouthEast;
            if (AnchorIntersects(pt, (left + right) >> 1, bottom + AnchorHalfSize))
                return DesignerAnchor.South;
            if (AnchorIntersects(pt, left - AnchorHalfSize, bottom + AnchorHalfSize))
                return DesignerAnchor.SouthWest;
            if (AnchorIntersects(pt, left - AnchorHalfSize, (top + bottom) >> 1))
                return DesignerAnchor.West;
            return null;
        }

        public DesignerController(DesignerPanel panel, Control delegationObject)
            : base(panel)
        {
            this.delegationObject = delegationObject;
            this.designPanel = panel;
            anchorVisibility = 0x7fffffff;
        }
 

        public override void OnDraw(Graphics g)
        {
            switch (state)
            {
                case DesignerState.Resizing:
                    OnDrawResizing(g);
                    break;
                case DesignerState.Moving:
                    OnDrawMoving(g);
                    break;
            }
        }

        private void DrawAnchor(Graphics g, int x, int y, Brush brush, Pen pen)
        {
            x = x - AnchorHalfSize;
            y = y - AnchorHalfSize;
            int size = AnchorHalfSize * 2 - 1;
            g.FillRectangle(brush, x, y, size, size);
            g.DrawRectangle(pen, x, y, size, size);
        }
        private void OnDrawResizing(Graphics g)
        {
            //draw anchors
            Rectangle rect = delegationObject.TransformedGeometry;
            int left = rect.Left;
            int top = rect.Top;
            int bottom = rect.Bottom;
            int right = rect.Right;
            Brush brush = Brushes.White;
            Pen pen = Pens.Black;

            if (isReference)
            {
                pen = Pens.White;
                brush = Brushes.Black;
            }
            if (delegationObject.Locked)
            {
                brush = Brushes.DarkOrange;
                pen = Pens.Black;
            }

            if ((anchorVisibility & (1 << (int)DesignerAnchor.NorthWest)) != 0)
                DrawAnchor(g, left - AnchorHalfSize, top - AnchorHalfSize, brush, pen);
            if ((anchorVisibility & (1 << (int)DesignerAnchor.North)) != 0)
                DrawAnchor(g, (left + right) >> 1, top - AnchorHalfSize, brush, pen);
            if ((anchorVisibility & (1 << (int)DesignerAnchor.NorthEast)) != 0)
                DrawAnchor(g, right + AnchorHalfSize, top - AnchorHalfSize, brush, pen);

            if ((anchorVisibility & (1 << (int)DesignerAnchor.East)) != 0)
                DrawAnchor(g, right + AnchorHalfSize, (top + bottom) >> 1, brush, pen);

            if ((anchorVisibility & (1 << (int)DesignerAnchor.SouthEast)) != 0)
                DrawAnchor(g, right + AnchorHalfSize, bottom + AnchorHalfSize, brush, pen);
            if ((anchorVisibility & (1 << (int)DesignerAnchor.South)) != 0)
                DrawAnchor(g, (left + right) >> 1, bottom + AnchorHalfSize, brush, pen);
            if ((anchorVisibility & (1 << (int)DesignerAnchor.SouthWest)) != 0)
                DrawAnchor(g, left - AnchorHalfSize, bottom + AnchorHalfSize, brush, pen);

            if ((anchorVisibility & (1 << (int)DesignerAnchor.West)) != 0)
                DrawAnchor(g, left - AnchorHalfSize, (top + bottom) >> 1, brush, pen);



        }
        private void OnDrawMoving(Graphics g)
        {
            //g.DrawRectangle(Pens.Black);
        }
    }
}
